package com.tc.kqdemo.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import com.tc.kqdemo.pojo.ConfigData;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Formatter;
import java.util.List;

@Service
public class DingDing {
    @Autowired
    private ConfigData t;

    //获取access_token
    public String getAccess_token(){
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setCorpid(t.getCorpId());
        request.setCorpsecret(t.getCorpSecret());
        request.setHttpMethod("GET");
        OapiGettokenResponse response=null;
        try {
            response = client.execute(request);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        if (response!=null){
            //System.out.println(JSON.toJSONString(response));
            if (response.getErrcode()==0&&response.getErrmsg().equals("ok")){
                return response.getAccessToken();
            }
        }
        return null;
    }

    //获取用户身份信息
    public OapiUserGetResponse getEmpInfo(String userid, String access_token){
        //String access_token = getAccess_token();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
        OapiUserGetRequest request = new OapiUserGetRequest();
        request.setUserid(userid);
        request.setHttpMethod("GET");
        OapiUserGetResponse res_=null;
        try {
            if (access_token!=null){
                res_ = client.execute(request, access_token);
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        //System.out.println(JSON.toJSONString(res_)+"<------getEmpInfo");
        return res_;
    }

    //(一)签名方法_1
    //数据生成签名   默认MD5
    private String sign(String content){
        String strDes="seedForOrgUploadAttendance"+content;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            //MessageDigest md = MessageDigest.getInstance("SHA-1");    //安全hash算法
            md.reset();
            md.update(strDes.getBytes("UTF-8"));//根据参数产生hash值
             return bytesToHex(md.digest());
            //return bytesToHexString(md.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
    //将bytes类型的数据转化为16进制类型
    private  String bytesToHex(byte[] hash) {                    //将字符串转化为16进制的数据
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    /*
     * json={sign:"",content:"corpid+userid+equipId+address+pic_address+time"}
     * sing:签名    算法:md5  content+seedForOrgUploadAttendance
     * */
    //写入数据到考勤打卡数据中-------------------该接口有权限的问题,可能没有调用该接口的权限与corpSecret有关
    public boolean readIntoData(String userid,String address,String equipid,String pic_add,long time,String access_token){
        System.out.println(userid+"号员工,刷脸数据写入钉钉考勤打卡开始!!!!"+new Date());
        String url="https://oapi.dingtalk.com/attendance/uploadCheckRecord?access_token="+access_token;
        String sign=null;
        String content=null;
        JSONObject js = new JSONObject();
        if (StringUtils.isNotBlank(userid) && StringUtils.isNotBlank(address)&& StringUtils.isNotBlank(equipid)
                && StringUtils.isNotBlank(pic_add)){
            content=t.getCorpId()+","+userid+","+address+","+equipid+","+pic_add+","+time;
            sign = sign(content);//<--------签名
            js.put("sign",sign);
            js.put("content",content);
        }else{
            js.put("sign","");
            js.put("content","");
        }
        System.out.println("考勤打卡接口的请求体:body===="+js);
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
        CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
        httpPost.setConfig(requestConfig);
        StringEntity se = new StringEntity(js.toString(), "utf-8");
        se.setContentType("application/json");
        httpPost.setEntity(se);
        CloseableHttpResponse res=null;
        try {
             res = httpClient.execute(httpPost);
            int code = res.getStatusLine().getStatusCode();
            if (code==HttpStatus.SC_OK){
                System.out.println("服务器正常响应!!!!");
                JSONObject json = JSON.parseObject(EntityUtils.toString(res.getEntity()));
                System.out.println(JSON.toJSONString(json)+"<---------考勤打卡---------返回的结果===userid:==="+userid);
                if(json!=null){
                    if (json.getInteger("errcode")==0&&json.getString("errmsg").equals("ok")){
                        return true;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (res!=null){
                    res.close();
                }
                if (httpClient!=null){
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println(userid+"号员工,刷脸数据写入钉钉考勤打卡结束!!!!"+new Date());
        return false;
    }

    //企业通讯录员工搜索
    public JSONObject searchEmp(String character_,String access_token){
        System.out.println("搜索的参数:"+character_+"<<<character_,,,access_token>>>>>"+access_token);
        DingTalkClient client = new DefaultDingTalkClient("https://eco.taobao.com/router/rest");
        CorpEmpSearchRequest req = new CorpEmpSearchRequest();
        req.setKeyword(character_);
        req.setOffset(0L);
        req.setSize(10L);
        CorpEmpSearchResponse rsp = null;
        try {
            if (access_token!=null){
                rsp = client.execute(req, access_token);
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        //System.out.println("==企业通讯录员工搜索==:"+JSON.toJSONString(rsp));
        JSONObject js = new JSONObject();
        if (rsp!=null&&(!rsp.getResult().equals("")||rsp.getResult()!=null)){
            JSONObject jsonObject = JSON.parseObject(rsp.getResult());
            //System.out.println("==企业通讯录员工搜索==:"+rsp.getResult());
            JSONArray list = jsonObject.getJSONArray("list");
            if (list.size()>0){
                String  userId = JSON.parseObject(list.get(0).toString()).getString("staffId");
                String name=JSON.parseObject(list.get(0).toString()).getString("name");
                js.put("userid",userId);
                js.put("name",name);
            }
        }else{
            js.put("userid","");
            js.put("name","");
        }
        return js;
    }



    //发送钉钉消息------推送消息
    public  void sendMsg(String userid,String content,String access_token){
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setUseridList(userid);
        request.setAgentId(Long.parseLong(t.getAgentId()));//在钉钉内以谁的名义发送消息给员工或者领导
        request.setToAllUser(false);
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("text");
        msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
        msg.getText().setContent(content);
        request.setMsg(msg);
        OapiMessageCorpconversationAsyncsendV2Response rsp=null;
        try {
            if (access_token!=null){
                rsp = client.execute(request,access_token);
            }else{
                System.out.println("access_token为空!!!!!!");
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        if (rsp!=null){
            if (rsp.isSuccess()){
                System.out.println("发送消息成功!!!!!!");
            }else{
                System.out.println("消息发送失败@!!!!1");
            }
        }
    }

    //获取考勤打卡的结果
    public void getResult(List<String> idList,String date1,String date2,String access_token){
        SimpleDateFormat d1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat d2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/list");
        OapiAttendanceListRequest request = new OapiAttendanceListRequest();
        request.setWorkDateFrom(date1);   //date1="2018-05-01 00:00:00"
        request.setWorkDateTo(date2);
        request.setUserIdList(idList);//Arrays.asList("1226682231742708")
        request.setOffset(0L);
        request.setLimit(50L);
        OapiAttendanceListResponse resp=null;
        try {
            System.out.println();
            if (access_token!=null){
                resp= client.execute(request,access_token);
            }else{
                System.out.println("access_token为空!!!!!!");
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        String result="";
        ArrayList<Object> arr = new ArrayList<>();
        if (resp!=null){
            if (resp.getErrcode()==0&&resp.getErrmsg().equals("ok")){
                List<OapiAttendanceListResponse.Recordresult> reList = resp.getRecordresult();
                if (reList.size()>0){
                    for (OapiAttendanceListResponse.Recordresult t:reList) {

                        JSONObject js = new JSONObject();
                        String res_ = t.getTimeResult();
                        if (res_.equals("Normal")){
                            result="正常";
                        }else if (res_.equals("Early")){
                            result="早退";
                        }else if (res_.equals("Late")){
                            result="迟到";
                        }else if (res_.equals("SeriousLate")){
                            result="严重迟到";
                        }else if (res_.equals("Absenteeism")){
                            result="旷工迟到";
                        }else if (res_.equals("NotSigned")){
                            result="未打卡";
                        }
                        OapiUserGetResponse info = getEmpInfo(t.getUserId(),access_token);
                        if (info!=null){
                            js.put("name",info.getName());
                        }else{
                            js.put("name","");
                        }
                        js.put("userid",t.getUserId());
                        js.put("type",t.getCheckType());
                        js.put("workDate",d1.format(t.getWorkDate()));
                        js.put("checkTime",d2.format(t.getUserCheckTime()));
                        js.put("result",result);
                        js.put("sourceType",t.getSourceType());
                        arr.add(js);
                    }
                }
            }
        }
        System.out.println(JSON.toJSONString(arr)+"<-------------打卡结果!!!!!!!!!!");
    }

    //考勤打卡详细记录
    // 参数 list的长度不能超过50
    public List<OapiAttendanceListRecordResponse.Recordresult> listRecoderDetail(String access_token, String startTime, String endTime, List<String> list) {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/listRecord");
        OapiAttendanceListRecordRequest request = new OapiAttendanceListRecordRequest();
        request.setCheckDateFrom(startTime);
        request.setCheckDateTo(endTime);
        request.setUserIds(list);
        OapiAttendanceListRecordResponse resp=null;
        try {
            resp= client.execute(request,access_token);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        //System.out.println(JSON.toJSONString(resp)+"<-------考勤详细记录");
        if (resp!=null){
            if (resp.getErrcode()==0&&resp.getErrmsg().equals("ok")){
                return resp.getRecordresult();
            }
        }
        return null;
    }

    //获取部门列表
    public JSONObject deptList(String id,Boolean fetch_child,String access_token){
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/list");
        OapiDepartmentListRequest request = new OapiDepartmentListRequest();
        request.setId(id);
        request.setHttpMethod("GET");
        request.setFetchChild(fetch_child);
        OapiDepartmentListResponse response=null;
        try {
            if (access_token!=null){
                response = client.execute(request, access_token);
            }
            // System.out.println(JSON.toJSONString(response)+"<--------------部门列表");
        } catch (ApiException e) {
            e.printStackTrace();
        }
        JSONObject res = new JSONObject();

        List<Long> ids = new ArrayList<>();//部门id列表
        List<String> names = new ArrayList<>();//部门名称列表
        List<Object> depts = new ArrayList<>();
        if(response!=null&&response.getErrcode()==0){
            List<OapiDepartmentListResponse.Department> departmentList = response.getDepartment();
            if(departmentList.size()>0){
                for (OapiDepartmentListResponse.Department d:departmentList) {
                    ids.add(d.getId());
                    names.add(d.getName());
                    JSONObject dept = new JSONObject();
                    dept.put("id",d.getId());
                    dept.put("name",d.getName());
                    depts.add(dept);
                }
            }
            res.put("deptIds",ids);
            res.put("deptNames",names);
            res.put("depts",depts);
        }
        return res;
    }

    //获取部门用户(详情)
    public List<OapiUserListbypageResponse.Userlist> getDept_Emp_Detail(String access_token, String deptid){
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/listbypage");
        OapiUserListbypageRequest request = new OapiUserListbypageRequest();
        request.setDepartmentId(Long.parseLong(deptid));
        request.setOffset(0L);
        request.setSize(100L);
        request.setOrder("entry_desc");
        request.setHttpMethod("GET");
        OapiUserListbypageResponse execute=null;
        try {
            if (access_token!=null){
                execute= client.execute(request,access_token);
            }else{
                System.out.println("access_token为空!!!!");
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        //System.out.println(JSON.toJSONString(execute)+"===============");
        if (execute!=null){
            if (execute.getErrcode()==0&&execute.isSuccess()&&execute.getErrmsg().equals("ok")){
                return execute.getUserlist();
            }
        }
        return null;
    }



    //获取部门用户的userid列表
    public List<String> getDeptMembers(String deptid,String access_token){
        //String access_token = getAccess_token();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/getDeptMember");
        OapiUserGetDeptMemberRequest req = new OapiUserGetDeptMemberRequest();
        req.setDeptId(deptid);
        req.setHttpMethod("GET");
        OapiUserGetDeptMemberResponse rsp=null;
        try {
             rsp = client.execute(req, access_token);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        if (rsp!=null){
            if (rsp.getErrcode()==0){
                return rsp.getUserIds();
            }
        }
        return null;
    }

    //创建部门
    public void createDept(){
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/create");
        OapiDepartmentCreateRequest req = new OapiDepartmentCreateRequest();
        req.setName("测试部");
        req.setParentid("1");
        req.setOrder("1");
        req.setCreateDeptGroup(true);
        req.setDeptHiding(false);
        req.setSourceIdentifier("测试_");
        OapiDepartmentCreateResponse resp=null;
        try {
             resp = client.execute(req, getAccess_token());
        } catch (ApiException e) {
            e.printStackTrace();
        }
        System.out.println(resp.toString()+"<------------------创建部门");
    }

    //获取部门详情
    public OapiDepartmentGetResponse deptInfo(String deptid, String access_token){
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/get");
        OapiDepartmentGetRequest req = new OapiDepartmentGetRequest();
        req.setId(deptid);
        req.setTopHttpMethod("GET");
        OapiDepartmentGetResponse resp=null;
        try {
           resp = client.execute(req, access_token);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        ArrayList<String> manaArr = new ArrayList<>();
        if(resp!=null){
            if(resp.getErrcode()==0){
                String name = resp.getName();
                String managerList = resp.getDeptManagerUseridList();
                if (managerList.contains("|")){
                    String[] mana = managerList.split("|");
                    if (mana.length>0){
                        for (String m : mana) {
                            manaArr.add(m);
                        }
                    }
                }else{
                    manaArr.add(managerList);
                }
                System.out.println("钉钉中的部门的名称---------->"+name);
                System.out.println("主管该部门的人员id列表============"+manaArr);
                return resp;
            }
        }
        return null;
    }

    //获取用户的主管的部门列表和角色组名称列表
    public JSONObject authority(String userid){
        System.out.println("权限的获取,userid====="+userid);
        String access_token = getAccess_token();
        OapiUserGetResponse empInfo = getEmpInfo(userid,access_token);
        ArrayList<String> leaderDpets = new ArrayList<>();
        ArrayList<String> groupName = new ArrayList<>();
        if (empInfo!=null){
            //主管的部门列表
            String isLeaderInDepts = empInfo.getIsLeaderInDepts();
            isLeaderInDepts=isLeaderInDepts.substring(1,isLeaderInDepts.length()-2);
            String[] arrLeaderDepts = isLeaderInDepts.split(",");
            if (arrLeaderDepts.length>0){
                for (String item:arrLeaderDepts) {
                    if (item.endsWith(":true")){
                        leaderDpets.add(item.substring(0,item.length()-":true".length()));
                    }
                }
            }
            //角色
            List<OapiUserGetResponse.Roles> roles = empInfo.getRoles();
            if (roles.size()>0){
                for (OapiUserGetResponse.Roles r:roles) {
                    groupName.add(r.getGroupName());
                }
            }else{
                System.out.println("------------未分配角色----------,"+userid);
            }
        }
        JSONObject js = new JSONObject();
        js.put("groupName",groupName);
        js.put("leaderDepts",leaderDpets);
        return js;
    }

    // java请求POST发送json格式请求
    //创建成员<---------------无问题    post请求   body为json格式数据
    public void createEmp(String name_,List dept,String tele,String jobnumber) {
        String access_token = getAccess_token();
        String url="https://oapi.dingtalk.com/user/create?access_token="+access_token;
        System.out.println(url+"<-------------请求的url链接!!!!");
        //请求钉钉接口创建人员
        JSONObject js = new JSONObject();
        js.put("name",name_);
        js.put("department",dept);
        js.put("mobile",tele);
        js.put("jobnumber",jobnumber);
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
        CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
        httpPost.setConfig(requestConfig);
        StringEntity se = new StringEntity(js.toString(), "utf-8");
        se.setContentType("application/json");
        httpPost.setEntity(se);

        try {
            HttpResponse response  = httpClient.execute(httpPost);
            int code = response.getStatusLine().getStatusCode();
            if (code==HttpStatus.SC_OK){
                System.out.println("服务器正常响应!");
                JSONObject json = JSON.parseObject(EntityUtils.toString(response.getEntity()));
                System.out.println(JSON.toJSONString(json)+"<------------------返回的结果");

            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    //(二)签名方法_2
    private static String md5(String content) {
        if (StringUtils.isBlank(content)) {
            return null;
        }
        content="seedForOrgUploadAttendance"+content;
        StringBuffer outStrBuf=null;
        try {
            byte[] b = content.getBytes("UTF-8");
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.reset();
            md.update(b);
            byte[] hash = md.digest();
            //将bytes类型的数据转化为16进制类型
            outStrBuf = new StringBuffer(32);
            for (int i = 0; i < hash.length; i++) {
                int v = hash[i] & 0xFF;
                if (v < 16) {
                    outStrBuf.append('0');
                }
                outStrBuf.append(Integer.toString(v, 16).toLowerCase());
            }
            return outStrBuf.toString();
        } catch (Exception e) {
            System.out.println("sign_utils签名错误");
            e.printStackTrace();
        }finally {
            if (outStrBuf!=null){
                outStrBuf=null;
            }
        }
        return null;
    }
























    //测试方法的入口
    public static void main(String[] args) {
        DingDing dd = new DingDing();


    }









}
